﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//using System.Numerics.BigInteger;

namespace Fibonachi
{
	// Кэширующий класс (выполняет мемоизацию)
	public static class Memoizers
	{
		public static Func<T, R> Memoize<T, R>(this Func<T, R> func)
		{
			var cache = new Dictionary<T, R>();
			return (x) =>
			{
				R result = default(R);
				if (cache.TryGetValue(x, out result))
				{
					return result;
				}
				result = func(x);
				cache[x] = result;
				return result;
			};
		}
	}

	class Program
	{
		static void Main(string[] args)
		{
			Func<ulong, ulong> fibo = null;
			fibo = y => y > 1 ? fibo(y - 1) + fibo(y - 2) : y;
			// Для ускорения расчёта применяется мемоизация (кэширование уже расчитанных значений в куче)
			// http://www.rsdn.ru/article/dotnet/cslambda.xml
			fibo = fibo.Memoize();
			Console.Write("Введите целое число (1-1000): ");
			UInt64 Number = ulong.Parse(Console.ReadLine());
			if ((Number > 0) && (Number <= 1000))
				Console.WriteLine("Число Фибоначи  = " + fibo(Number));
			else
				Console.WriteLine("Введено неверное значение для расчёта");
		}
	}
}
